package com.daybreak.config;

import com.daybreak.component_security.LoginFailedHandler;
import com.daybreak.component_security.LoginSuccessHandler;
import com.daybreak.component_security.LoginValidateProvider;
import com.daybreak.component_security.MyAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * SpringSecurity主配置类
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    //security的鉴权排除的url列表
    private static final String[] excludedAuthPages = {
            "/auth/login",
            "/auth/logout",
            "/health",
            "/api/socket/**",
            "/noRole.html",
            "/**/*.ico"
    };

    //自定义的登录验证器
    @Autowired
    private LoginValidateProvider loginValidateProvider;

    //登录成功时调用的自定义处理类
    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    //登录失败时调用的自定义处理类
    @Autowired
    private LoginFailedHandler loginFailedHandler;

    //无权限访问被拒绝时的自定义处理器。如不自己处理，默认返回403错误
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //基础设置
        http
            .authorizeRequests()
            .antMatchers(excludedAuthPages).permitAll()  //无需进行权限过滤的请求路径
//           .antMatchers("/login.html").permitAll()  //无需进行权限过滤的请求路径
            .antMatchers(HttpMethod.OPTIONS).permitAll() //option 请求默认放行
            .anyRequest().authenticated()//其他请求都需要认证
           .anyRequest().access("@rbacService.hasPermission(request,authentication)")//认证通过后，需要通过鉴权才能继续访问
           .antMatchers("/user/ha").hasAnyRole("USER")
            .and().formLogin() //登录表单
            .usernameParameter("username") //指定前端发过来的用户名字段
            .passwordParameter("password") //指定前端发过来的密码字段
           .loginProcessingUrl("/auth/login") //指定前端登录时请求的url
            .loginPage("/login.html")
            .defaultSuccessUrl("/index")//成功登录跳转
//            .successHandler(loginSuccessHandler)//成功登录处理器
            .failureHandler(loginFailedHandler)//失败登录处理器
             .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login.html") //退出登录
            .permitAll()//登录成功后有权限访问所有页面
                .and()
                .exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);//访问被拒绝时自定义处理器

        //关闭csrf跨域攻击防御
        http.csrf().disable();

        System.out.println("配置完成！");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //这里要设置自定义登录认证器
        auth.authenticationProvider(loginValidateProvider);
    }
}
